package calao.client.ui;

import java.util.Vector;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;

public class FastTable 
extends HTMLTable
{

	int columnCount = -1;

	private int totalCellCount = 0;
	private int rowCount = 0;
	private Element lastRow;
	private int lastRowCellCount;
	private int lastRowSize;
	private Vector cellCount = new Vector();
	
	public FastTable()
	{
		setCellFormatter(new CellFormatter());
	    setRowFormatter(new RowFormatter());
	    setColumnFormatter(new ColumnFormatter());
	}

	public FastTable(int numColumns)
	{
		this();
		this.columnCount = numColumns;
	}
	
	public int getCellCount(int row) 
	{
		if (row<cellCount.size()) return ((Integer)cellCount.get(row)).intValue();
		else if (row==rowCount-1) return lastRowCellCount;
		else throw new IndexOutOfBoundsException();
	}
	
	public int getCellCount()
	{
		return totalCellCount;
	}

	public int getRowCount() 
	{
		return rowCount;
	}

	protected void prepareCell(int row, int column) 
	{		
	}

	protected void prepareRow(int row) 
	{
	}
	
	protected Element addCell(int colSpan, String style, Widget widget, String text)
	{
		if (lastRow==null || lastRowSize==columnCount) {
			if (lastRow!=null) cellCount.add(new Integer(lastRowCellCount));
			lastRow = DOM.createTR();
			DOM.appendChild(getBodyElement(), lastRow);
			rowCount++;
			lastRowSize = lastRowCellCount = 0;
		}
		Element cell = createCell();
		DOM.appendChild(lastRow, cell);
		if (colSpan>1) {
			DOM.setElementPropertyInt(cell, "colSpan", colSpan);
		}
		if (style!=null) {
			UIObject.setStyleName(cell, style, true);
		}
		if (widget!=null) {
			setWidget(rowCount-1, lastRowCellCount, widget);
		}
		else if (text!=null) {
			DOM.setInnerText(cell, text);
		}
		lastRowSize += colSpan;
		lastRowCellCount++;
		totalCellCount++;
		return cell;
	}
	
	public Element addCell()
	{
		return addCell(1, null, null, null);
	}
	
	public void addCells(int numCells)
	{
		for (int i=0; i<numCells; i++) addCell();
	}
	
	public Element addCell(Widget widget)
	{
		return addCell(1, null, widget, null);
	}

	public Element addCell(Widget widget, int colSpan)
	{
		return addCell(colSpan, null, widget, null);
	}

	public Element addCell(Widget widget, int colSpan, String style)
	{
		return addCell(colSpan, style, widget, null);
	}
	
	public Element addCell(String text)
	{
		return addCell(1, null, null, text);
	}

	public Element addCell(String text, int colSpan)
	{
		return addCell(colSpan, null, null, text);
	}

	public Element addCell(String text, int colSpan, String style)
	{
		return addCell(colSpan, style, null, text);
	}

	public Element addEmptyCell()
	{
		return addCell(1, null, null, null);
	}
	
	public Element addEmptyCell(int colSpan)
	{
		return addCell(colSpan, null, null, null);
	}

	public Element addEmptyCell(int colSpan, String style)
	{
		return addCell(colSpan, style, null, null);
	}

	public void completeRow()
	{
		if (columnCount>lastRowSize) {
			addCell(columnCount-lastRowSize, null, null, null);
		}
	}

	public int getColumnCount() {
		return columnCount;
	}

	public void setColumnCount(int columnCount) {
		this.columnCount = columnCount;
	}
	
	/** Gets the current column position.
	 * @return The index of the column at which the next cell will be added.
	 */
	public int getColumn()
	{
		return lastRowSize==columnCount? 0 : lastRowSize;
	}
	
}
